package io.kiki.sba.registry.server.metadata.remoting.handler;

import io.kiki.sba.registry.api.Channel;
import io.kiki.sba.registry.common.model.ServerData;
import io.kiki.sba.registry.common.model.console.PersistenceData;
import io.kiki.sba.registry.common.model.metaserver.FetchSystemPropertyRequest;
import io.kiki.sba.registry.common.model.metaserver.FetchSystemPropertyResult;
import io.kiki.sba.registry.common.model.metaserver.ProvideData;
import io.kiki.sba.registry.server.metadata.provide.data.ProvideDataService;
import io.kiki.sba.registry.store.api.DBResponse;
import io.kiki.sba.registry.store.api.OperationStatus;
import io.kiki.sba.registry.util.StringUtil;
import lombok.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Handle session node's query request
 */
public class FetchSystemPropertyRequestHandler extends BaseMetaServerHandler<FetchSystemPropertyRequest> {

    private static final Logger logger = LoggerFactory.getLogger(FetchSystemPropertyRequestHandler.class);

    @Autowired
    private ProvideDataService provideDataService;

    @Override
    public void checkParam(@NonNull FetchSystemPropertyRequest request) {

        StringUtil.checkNotBlank(request.getDataInfoId(), "dataInfoId");
    }

    @Override
    public Object doHandle(Channel channel, FetchSystemPropertyRequest request) {
        try {
            logger.info("get system data {}", request);

            return fetchSystemData(request);
        } catch (Exception e) {
            logger.error("get system data {} from db error!", request.getDataInfoId(), e);
            throw new RuntimeException("Get system data from db error!", e);
        }
    }

    private Object fetchSystemData(FetchSystemPropertyRequest request) {
        DBResponse<PersistenceData> ret = provideDataService.queryProvideData(request.getDataInfoId());
        OperationStatus status = ret.getOperationStatus();
        PersistenceData persistenceData = ret.getEntity();

        if (status == OperationStatus.notfound) {
            FetchSystemPropertyResult result = new FetchSystemPropertyResult(false);
            logger.warn("has not found system data from DB dataInfoId:{}", request.getDataInfoId());
            return result;
        }
        ProvideData data = new ProvideData(new ServerData(persistenceData.getData()), request.getDataInfoId(), persistenceData.getVersion());

        return processResult(request, status, data);
    }

    private Object processResult(FetchSystemPropertyRequest request, OperationStatus status, ProvideData data) {
        if (status == OperationStatus.success) {
            FetchSystemPropertyResult result;
            if (data.getVersion() > request.getVersion()) {
                result = new FetchSystemPropertyResult(true, data);
            } else {
                result = new FetchSystemPropertyResult(false);
            }
            logger.info("[fetchSystemProperty]dataInfoId={} req={} res={}", request.getDataInfoId(), request.getVersion(), data.getVersion());

            return result;
        } else {
            logger.error("get Data DB status error!");
            throw new RuntimeException("Get Data DB status error!");
        }
    }

    @Override
    public Class interest() {
        return FetchSystemPropertyRequest.class;
    }


    public FetchSystemPropertyRequestHandler setProvideDataService(ProvideDataService provideDataService) {
        this.provideDataService = provideDataService;
        return this;
    }
}
